package com.iwayin.core.bo.answer;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.iwayin.core.bo.BaseBO;
import com.iwayin.core.bo.EmailServiceUtil;
import com.iwayin.core.dao.answer.AnswerDAO;
import com.iwayin.core.dao.ask.AskDAO;
import com.iwayin.core.dao.follow.FollowDAO;
import com.iwayin.core.dao.setting.EmailSettingDAO;
import com.iwayin.core.dao.user.UserDAO;
import com.iwayin.core.dao.vote.AnswerVoteDAO;
import com.iwayin.core.dataobject.AnswerDO;
import com.iwayin.core.dataobject.AnswerVoteDO;
import com.iwayin.core.dataobject.AskDO;
import com.iwayin.core.dataobject.EmailSettingDO;
import com.iwayin.core.dataobject.FollowDO;
import com.iwayin.core.dataobject.UserDO;
import com.iwayin.core.utils.exception.BOException;
import com.iwayin.core.vo.AnswerVO;

public class AnswerBOImpl extends BaseBO implements AnswerBO {
	private AskDAO askDAO;
	private AnswerDAO answerDAO;
	private AnswerVoteDAO answerVoteDAO;
	private UserDAO userDAO;
	private FollowDAO followDAO;
	private EmailSettingDAO emailSettingDAO;

	@Override
	public void addAnswer(AnswerDO answer) {
		AskDO ask = this.askDAO.findAskByAskId(answer.getAskId());
		String msg = meCanAnswerAsk(ask, answer);
		if (msg != null) {
			throw new BOException(msg);
		}
		try {
			// 添加观点,vote_count+1
			Long answerId = answerDAO.addAnswer(answer);
			askDAO.askAnswerCountPlusOne(ask.getId());
			// 之前投票
			AnswerVoteDO query = new AnswerVoteDO();
			query.setAskId(ask.getId());
			query.setUserId(answer.getUserId());
			AnswerVoteDO vote = answerVoteDAO.getByAskIdUserId(query);
			if (vote == null) {
				query.setAnswerId(answerId);
				answerVoteDAO.addAnswerVote(query);
				askDAO.voteCountPlusOne(ask.getId());
			} else {
				answerDAO.answerVoteCountDownOne(vote.getAnswerId());
				// 更新投票
				vote.setAnswerId(answerId);
				answerVoteDAO.updateVoteByAskIdUserId(vote);
			}
			//是否立即email通知ask人
			//为自己的ask添加答案，不必发送邮件提醒，同时消息不必记录
			if (answer.getUserId().equals(ask.getUserId())) {
				return;
			}
			EmailSettingDO es = emailSettingDAO.getEmailSettingDO(ask.getUserId());
			if (es != null
					&& EmailSettingDO.USER_EMAIL_NOTIFICATION_IMMEDIATELY
							.equals(es.getAnswers())) {
				UserDO asker = userDAO.getEmailReceiver(ask.getUserId());
				UserDO anserUser = userDAO.getUserById(answer.getUserId());
				Map<String, Object> param = new HashMap<String, Object>();
				param.put("avatar", anserUser.getAvatarPath());
				param.put("nickname", anserUser.getNickname());
				param.put("answer", answer.getAnswerBody());
				param.put("askId", ask.getId().toString());
				param.put("askInfo", ask.getQuestion());
				param.put("userId", answer.getUserId().toString());
				EmailServiceUtil.sendAnswerEmail(asker.getLoginName(), param);
			}
		} catch (Exception e) {
			throw new BOException(e);
		}
	}

	private String meCanAnswerAsk(AskDO ask, AnswerDO answer) {
		// 问问状态校验
		if (ask == null || ask.getStatus().equals(0l)) {
			return "问问已被删除";
		}
		if (ask.getStatus().equals(2l)) {
			return "问问已被关闭";
		}
		// 观点个数，临时限定
		if (ask.getAnswerCount().equals(10l)) {
			return "观点已满,赞同的观点投一票吧";
		}
		// 是否许可添加观点
		if (ask.getPreventOther().equals(0l) && !ask.getUserId().equals(answer.getUserId())) {
			return "受保护问问,不能添加观点,但可以投票哦";
		}
		// 一个人只能有一个观点
		List<AnswerDO> list = answerDAO.findAnswerByAskUserId(answer);
		if (list.size() > 0 && !ask.getUserId().equals(answer.getUserId())) {
			return "此问问你已经添加过观点";
		}
		// 是否有相同观点
		AnswerDO exist = answerDAO.findAnswerByBody(answer);
		if (exist != null) {
			return "有与你相同观点,直接投一票吧";
		}
		return null;
	}

	@Override
	public List<AnswerDO> findAnswers(AnswerDO query) {
		return this.answerDAO.findAnswers(query);
	}

	@Override
	public List<AnswerDO> findAnswers(AnswerDO query, Long myId) {
		List<AnswerDO> answers = this.answerDAO.findAnswers(query);
		double voteCount = 0, curVoteRate = 0;
		for (AnswerDO answer : answers) {
			voteCount += answer.getVoteCount();
		}
		for (int i = 0; i < answers.size(); i++) {
			AnswerDO ans = answers.get(i);
			double voteRate = 0;
			if (i == answers.size() - 1) {
				voteRate = 100 - curVoteRate;
			} else {
				voteRate = (int) (ans.getVoteCount() / voteCount * 100);
				curVoteRate += voteRate;
			}
			ans.setVoteRate((int) voteRate);
		}
		if (myId != null) {
			AnswerVoteDO answerVotequery = new AnswerVoteDO();
			answerVotequery.setAskId(query.getAskId());
			answerVotequery.setUserId(myId);
			AnswerVoteDO answerVote = answerVoteDAO.getByAskIdUserId(answerVotequery);
			if (answerVote != null) {
				for (AnswerDO answer : answers) {
					if (answer.getId().equals(answerVote.getAnswerId())) {
						answer.setIsAnswer(true);
						query.setIsAnswer(true);
					}
				}
			}
		}
		return answers;
	}

	@Override
	public List<AnswerVO> findAskReceivedAnswers(AnswerDO query,Long loginUserId) {
		List<AnswerVO> answers=new ArrayList<AnswerVO>();
		List<AnswerVoteDO> votes=this.answerVoteDAO.findAskVotesByAskId(query);
		for(AnswerVoteDO userVote:votes){
			UserDO user =this.userDAO.getUserById(userVote.getUserId());
			AnswerVO answerVO=new AnswerVO();
			answerVO.setAvatarPath(user.getAvatarPath());
			answerVO.setNickname(user.getNickname());
			answerVO.setUserId(user.getId());
			AnswerDO answer=this.answerDAO.findAnswerById(userVote.getAnswerId());
			answerVO.setAnswerBody(answer.getAnswerBody());
			FollowDO isFollow = followDAO.getFollower(loginUserId, user.getId());
			// 判断与当前登录用户关系
			answerVO.setFollow(isFollow == null ? false : true);
			answers.add(answerVO);
		}
		return answers;
	}

	@Override
	public List<AnswerDO> findAnswersByAskId(Long askId) {
		AnswerDO query = new AnswerDO();
		query.setAskId(askId);
		return this.findAnswers(query);
	}

	public void setAskDAO(AskDAO askDAO) {
		this.askDAO = askDAO;
	}

	public void setAnswerDAO(AnswerDAO answerDAO) {
		this.answerDAO = answerDAO;
	}

	public void setAnswerVoteDAO(AnswerVoteDAO answerVoteDAO) {
		this.answerVoteDAO = answerVoteDAO;
	}

	public void setUserDAO(UserDAO userDAO) {
		this.userDAO = userDAO;
	}

	public void setFollowDAO(FollowDAO followDAO) {
		this.followDAO = followDAO;
	}

	public void setEmailSettingDAO(EmailSettingDAO emailSettingDAO) {
		this.emailSettingDAO = emailSettingDAO;
	}
}
